package com.nidu.demo.oauth2.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.nidu.demo.common.constants.RequestHeaderConstants;
import com.nidu.demo.oauth2.model.OAuth2AccessToken;
import org.springframework.http.HttpHeaders;
import org.springframework.util.Base64Utils;

import javax.servlet.http.HttpServletRequest;

public class OAuth2Utils {

    /**
     * 从Basic认证头中获取客户端凭据
     *
     * @param request HTTP请求
     * @return [clientId, clientSecret]
     * @throws IllegalArgumentException 如果Basic认证头不存在或格式不正确
     */
    public static String[] getClientCredentials(HttpServletRequest request) {
        String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
        if (authHeader == null || !authHeader.startsWith(RequestHeaderConstants.AUTHORIZATION_BASIC)) {
            throw new IllegalArgumentException("Missing or invalid Authorization header");
        }

        String base64Credentials = authHeader.substring((RequestHeaderConstants.AUTHORIZATION_BASIC + " ").length()).trim();
        String credentials = new String(Base64Utils.decodeFromString(base64Credentials));
        String[] values = credentials.split(":", 2);
        if (values.length != 2) {
            throw new IllegalArgumentException("Invalid Basic authentication format");
        }

        return values;
    }

    /**
     * 构建授权码模式的重定向URL
     */
    public static String buildAuthorizationCodeRedirectUrl(String redirectUri, String code, String state) {
        return String.format("%s?code=%s%s", redirectUri, code, StrUtil.isNotEmpty(state) ? "&state=" + state : "");
    }

    /**
     * 构建简单模式的重定向URL
     */
    public static String buildImplicitRedirectUrl(String redirectUri, OAuth2AccessToken token, String state) {
        return String.format("%s#access_token=%s&token_type=%s&expires_in=%s&refresh_token=%s&scope=%s&client_id=%s%s",
                redirectUri, token.getAccessToken(), RequestHeaderConstants.AUTHORIZATION_BEARER,
                LocalDateTimeUtil.format(token.getExpiresTime(), DatePattern.NORM_DATETIME_PATTERN),
                token.getRefreshToken(), String.join(",", token.getScopes()), token.getClientId(),
                StrUtil.isNotEmpty(state) ? "&state=" + state : "");
    }

}
